home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Forever 4
/
Atari Forever 4.zip
/
Atari Forever 4.iso
/
SERIE_S
/
S_902
/
ABLEITEN
/
ABL_GEM.GFA
(
.txt
)
next >
Wrap
GFA-BASIC Atari
|
1998-03-14
|
13KB
|
594 lines
' Programm/Accessory zum Ableiten von Funktionen
$m30000
ON ERROR GOSUB err
window_install
DIM tr$(5)
tr$(1)="^"
tr$(2)="/"
tr$(3)="*"
tr$(4)="-"
tr$(5)="+"
a&=APPL_INIT()
IF a&=0
prg!=TRUE
hand&=@openw
v_slide
ELSE
menu&=MENU_REGISTER(a&," Ableiten")
WHILE menu&=-1 !zuviele einträge
~EVNT_MESAG(0)
WEND
ENDIF
'
'
DO
IF hand&<>-1
haupt
ELSE
~EVNT_MESAG(0)
fenster
ENDIF
LOOP
'
> PROCEDURE haupt
LOCAL f|
bezg&=64 !Mit A wird die Zerlegung begonnen
'
IF EVNT_MULTI(&X110000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,d&,d&,d&,d&,taste&,d&) AND 16
fenster
ENDIF
@cls
@print(" Symbolische Umformungen")
@print(" Dieses Programm bildet die Ableitungen von Funktionen.")
@print(" (c) Matthias Jüschke")
@print("")
REPEAT
@print(" Geben Sie den Term ein, der abgeleitet werden soll")
@print(" (Funktion laden: leere Eingabe):")
f$=@input$("f(x)=",70)
IF LEN(f$)=0
n$=""
IF @filese(n$)
IF EXIST(n$)
OPEN "i",#1,n$
LINE INPUT #1,f$
CLOSE #1
ENDIF
ENDIF
ENDIF
UNTIL LEN(f$)
@print("")
a$=@ableitung$(UPPER$(f$),ASC("Y"))
@print("")
@print(" Die Ableitung lautet:")
@print("f'(x)="+a$)
@print(" - Taste - ")
ALERT 1,"Ableitung|speichern?",2,"Ja|Nein",f|
IF f|=1
IF @filese(n$)
OPEN "O",#1,n$+".FKT"
PRINT #1,a$
PRINT #1,"ist die Ableitung der Funktion:"
PRINT #1,f$
CLOSE #1
ENDIF
ENDIF
~@key
RETURN
> PROCEDURE window_install
hand&=-1
wx&=0
wy&=51
ww&=480
wh&=262
line_anz&=(wh&-38)/16
x_aufl&=WORK_OUT(0)
y_aufl&=WORK_OUT(1)
text&=0
lines&=50
DIM t$(lines&)
RETURN
> FUNCTION openw
hand&=WIND_CREATE(&X111101111,wx&,wy&,x_aufl&,y_aufl&)
' vslide,Pf-up,down,Size,,move,full,close,name
titel$=" Ableiten "+CHR$(0) !titelw
~WIND_SET(hand&,2,CARD(SWAP(V:titel$)),CARD(V:titel$),0,0) !Titel
IF WIND_OPEN(hand&,wx&,wy&,ww&,wh&)=0
OUT 2,7
~WIND_DELETE(hand&)
hand&=-1
ELSE
v_slide
ENDIF
RETURN hand&
ENDFUNC
> PROCEDURE fenster
LOCAL wx1&,wy1&,ww1&,wh1&
IF MENU(1)=40
IF hand&=-1 AND prg!=0
hand&=@openw
ELSE
~WIND_SET(hand&,10,0,0,0,0) !TOPW
ENDIF
ENDIF
' IF hand&=MENU(4), außer bei 41
SELECT MENU(1)
CASE 20 !REDRAW
DEFMOUSE 2
~WIND_GET(hand&,11,wx1&,wy1&,ww1&,wh1&)
REPEAT
IF RC_INTERSECT(MENU(5),MENU(6),MENU(7),MENU(8),wx1&,wy1&,ww1&,wh1&)
CLIP wx1&,wy1&,ww1&,wh1&
redraw
ENDIF
~WIND_GET(hand&,12,wx1&,wy1&,ww1&,wh1&)
UNTIL ww1&=0 OR wh1&=0
DEFMOUSE 0
CLIP wx&+1,wy&+19,ww&-20,wh&-38
CASE 21,29 !TOPW
~WIND_SET(hand&,10,0,0,0,0)
CASE 22,41 !CLOSEW
IF hand&>-1
~WIND_GET(hand&,5,wx&,wy&,ww&,wh&)
IF ww&>0 AND wh&>0
~WIND_CLOSE(hand&)
~WIND_DELETE(hand&)
IF prg!
END
ENDIF
ENDIF
ENDIF
hand&=-1
CASE 23 !FULLW
~WIND_SET(hand&,5,0,19,x_aufl&,y_aufl&-19)
~WIND_GET(hand&,5,wx&,wy&,ww&,wh&)
line_anz&=(wh&-38)/16
CLIP wx&+1,wy&+19,ww&-20,wh&-38
v_slide
CASE 24 !ARROWED
wx1&=v_s&
SELECT MENU(5)
CASE 0 !über Pf
v_s&=MAX(v_s&-line_anz&,0)
CASE 1 !unter Pf
v_s&=MIN(v_s&+line_anz&,text&-line_anz&)
CASE 2 !Pf oben
v_s&=MAX(v_s&-1,0)
CASE 3 !pf unten
v_s&=MIN(v_s&+1,MAX(text&-line_anz&,0))
ENDSELECT
IF v_s&<>wx1&
v_slide
redraw
ENDIF
CASE 26 !VSLID
~WIND_SET(hand&,9,MENU(5),0,0,0) !auf Pos.setzen
v_s&=(MENU(5)*(text&-line_anz&)+500)/1000
redraw
CASE 27 !SIZE
~WIND_SET(hand&,5,MENU(5),MENU(6),MAX((MENU(7) AND &H0)+3,155-16),MAX((MENU(8) AND &H0)+6,150))
~WIND_GET(hand&,5,wx&,wy&,ww&,wh&)
line_anz&=(wh&-38)/16
CLIP wx&+1,wy&+19,ww&-20,wh&-38
IF v_s&>text&-line_anz& !kein nicht erlaubter Bereich
v_s&=MAX(text&-line_anz&,0)
ENDIF
v_slide
CASE 28 !MOVEW
wx&=MENU(5) AND &H1 !in 4er Schritten
wy&=(MENU(6) AND &H1)+3
~WIND_SET(hand&,5,wx&,wy&,ww&,wh&)
CLIP wx&+1,wy&+19,ww&-20,wh&-38
ENDSELECT
RETURN
> PROCEDURE v_slide
' Größe und Positionierung des Vertikalen Schiebers
LOCAL a&
a&=1000
IF text&
a&=(line_anz&)/text&*1000
ENDIF
~WIND_SET(hand&,16,a&,0,0,0) !Größe
IF text&-line_anz&
a&=v_s&/(text&-line_anz&)*1000
ENDIF
~WIND_SET(hand&,9,a&,0,0,0) !Position
RETURN
> PROCEDURE redraw
LOCAL i&
DEFFILL 0,0,0
PBOX wx&,wy&+19,wx&+ww&-19,wy&+wh&-19
FOR i&=v_s& TO MIN(text&+line_anz&,lines&)
TEXT wx&,wy&+(i&-v_s&)*16+16,t$(i&)
NEXT i&
RETURN
'
> PROCEDURE print(t$)
LOCAL i&,fertig!,redraw!
REPEAT
fertig!=TRUE
INC text&
IF text&>lines&
text&=lines&
FOR i&=2 TO lines&
SWAP t$(i&-1),t$(i&)
NEXT i&
redraw!=TRUE
ENDIF
t$(text&)=LEFT$(t$,76)
IF LEN(t$)>76
t$=RIGHT$(t$,LEN(t$)-76)
fertig!=FALSE
ENDIF
IF v_s&+line_anz&<text& OR redraw!
v_s&=MAX(text&-line_anz&,0)
IF fertig!
redraw
v_slide
ENDIF
ELSE
TEXT wx&,wy&+text&*16+16,t$(text&)
ENDIF
UNTIL fertig!
RETURN
> PROCEDURE cls
LOCAL i&
DEFFILL 0,0,0
PBOX wx&,wy&+19,wx&+ww&-19,wy&+wh&-19
FOR i&=0 TO lines&
t$(i&)=""
NEXT i&
text&=0
v_s&=0
v_slide
RETURN
> FUNCTION key
LOCAL rueck&
REPEAT
rueck&=EVNT_MULTI(&X10001,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,d&,d&,d&,d&,taste&,d&)
IF rueck& AND 10000
fenster
ENDIF
UNTIL rueck& AND 1
RETURN taste&
ENDFUNC
> FUNCTION filese(VAR n$)
LOCAL ok&,p$
p$=CHR$(GEMDOS(25)+65)+":"+DIR$(0)+"\*.FKT"
~FSEL_INPUT(p$,n$,ok&)
n$=LEFT$(p$,RINSTR(p$,"\"))+n$
RETURN ok&
ENDFUNC
> FUNCTION input$(t$,len&)
LOCAL rueck&,ret$,asc|,scan|
print(t$+"_")
REPEAT
rueck&=EVNT_MULTI(&X10001,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,d&,d&,d&,d&,taste&,d&)
' ^adr.buf
IF rueck& AND 1 !tastatur
asc|=taste& AND 255
scan|=(taste& DIV 256) AND 255
SELECT asc|
CASE 8
IF LEN(ret$)
ret$=LEFT$(ret$,LEN(ret$)-1)
ENDIF
CASE 32 TO 255
IF LEN(ret$)<len&
ret$=ret$+CHR$(asc|)
ENDIF
ENDSELECT
DEC text&
print(t$+ret$+"_ ")
ENDIF
IF rueck& AND &X10000
fenster
ENDIF
UNTIL asc|=13
RETURN ret$
ENDFUNC
> PROCEDURE err
t%=TIMER
REPEAT
OUT 2,7
UNTIL TIMER-t%>40
IF prg!
END
ELSE
DO
ON MENU 10000
LOOP
ENDIF
RETURN
'
'
'
> FUNCTION ableitung$(f$,bez&)
LOCAL t&,bezz&,pos&,a$,b$,a_abl$,b_abl$,ret$,vorz!
' t& :gibt, wenn sich f$ trennen läßt, den Wert der Trennung an
' bezz& :da bezg& verändert wird, der Wert aber noch benötigt wird
' pos& :die Stelle, an der f$ getrennt werden muß
' a$,b$ :bei t&>0 die Teilstrings bei t&>0
' sonst a$: elementare Funktion, b$:innere Funktion
' a_abl$,b_abl$ :bei t&>0 die Ableitungen von a$ und b$
' vorz! :das Vorzeichen von f$ (negativ=TRUE)
'
@print(CHR$(bez&)+"="+f$) !,
vorz!=@vorz(f$)
'
IF f$=""
@print("")
@print("Fehler: *,/,^ falsch gesetzt oder leere Eingabe/Klammer")
ENDIF
'
t&=@trenn(f$,pos&)
'
IF t&=0
IF @const(f$)
ret$="0"
ELSE IF f$="X"
ret$="1"
ELSE
pos&=INSTR(f$,"(")
IF pos&>1 AND RIGHT$(f$)=")"
INC bezg&
a$=LEFT$(f$,pos&-1)
@print(CHR$(bez&)+"="+a$+"("+CHR$(bezg&)+")")
b$=MID$(f$,pos&+1,LEN(f$)-pos&-1)
b_abl$=@ableitung$(b$,bezg&)
IF a$="SIN"
ret$=@mul$(b_abl$,"COS("+b$+")")
ELSE IF a$="COS"
ret$=@mul$(b_abl$,"-SIN("+b$+")")
ELSE IF a$="TAN"
ret$=@div$(b_abl$,@hoch$("COS("+b$+")","2"))
ELSE IF a$="COT"
ret$=@div$("-"+b_abl$,@hoch$("SIN("+b$+")","2"))
ELSE IF a$="ASIN"
ret$=@div$(b_abl$,"SQRT(1-"+@hoch$(b$,"2")+")")
ELSE IF a$="ACOS"
ret$=@div$("-"+b_abl$,"SQRT(1-"+@hoch$(b$,"2")+")")
ELSE IF a$="ATAN"
ret$=@div$(b_abl$,@add$("1",@hoch$(b$,"2")))
ELSE IF a$="ACOT"
ret$=@div$("-"+b_abl$,@add$("1",@hoch$(b$,"2")))
ELSE IF a$="SINH"
ret$=@mul$(b_abl$,"COSH("+b$+")")
ELSE IF a$="COSH"
ret$=@mul$(b_abl$,"SINH("+b$+")")
ELSE IF a$="TANH"
ret$=@mul$(b_abl$,"1-TANH("+b$+")^2")
ELSE IF a$="COTH"
ret$=@mul$(b_abl$,"1-COTH("+b$+")^2")
ELSE IF a$="ASINH"
ret$=@div$(b_abl$,"SQRT(1+"+@hoch$(b$,"2")+")")
ELSE IF a$="ACOSH"
ret$=@div$(b_abl$,"SQRT("+@hoch$(b$,"2")+"-1)")
ELSE IF a$="ATANH"
ret$=@div$(b_abl$,"1-"+@hoch$(b$,"2"))
ELSE IF a$="ACOTH"
ret$=@div$(b_abl$,"1-"+@hoch$(b$,"2"))
ELSE IF a$="SQRT"
ret$=@div$(b_abl$,@mul$("2","SQRT("+b$+")"))
ELSE IF a$="EXP"
ret$=@mul$(b_abl$,f$)
ELSE IF a$="LN"
ret$=@div$(b_abl$,b$)
ELSE IF a$="LOG"
ret$=@div$(b_abl$,@mul$("LN(10)",b$))
ELSE
@print("Fehler: "+a$+"() unbekannt")
ret$=f$+"'"
ENDIF
ELSE
@print("Fehler: "+f$+" ist unverständlich")
ret$=f$+"'"
ENDIF
ENDIF
ELSE !IF t&>0
ADD bezg&,2
a$=MID$(f$,1,pos&-1)
b$=MID$(f$,pos&+1)
IF vorz!
@print("-")
ENDIF
@print(CHR$(bez&)+"="+CHR$(bezg&-1)+tr$(t&)+CHR$(bezg&)+", "+CHR$(bezg&-1)+"="+a$+", "+CHR$(bezg&)+"="+b$)
'
bezz&=bezg&
a_abl$=@ableitung$(a$,bezg&-1)
b_abl$=@ableitung$(b$,bezz&)
'
IF t&=5 !add
ret$=@add$(a_abl$,b_abl$)
@print(CHR$(bez&+32)+"="+CHR$(bezz&-1+32)+"+"+CHR$(bezz&+32)) !,
ELSE IF t&=4 !sub
ret$=@sub$(a_abl$,b_abl$)
@print(CHR$(bez&+32)+"="+CHR$(bezz&-1+32)+"-"+CHR$(bezz&+32)) !,
ELSE IF t&=3 !mul
ret$=@add$(@mul$(a_abl$,b$),@mul$(a$,b_abl$))
@print(CHR$(bez&+32)+"="+CHR$(bezz&-1+32)+"*"+CHR$(bezz&)+"+"+CHR$(bezz&-1)+"*"+CHR$(bezz&+32)) !,
ELSE IF t&=2 !div
ret$=@div$(@sub$(@mul$(a_abl$,b$),@mul$(a$,b_abl$)),@hoch$(b$,"2"))
@print(CHR$(bez&+32)+"=("+CHR$(bezz&-1+32)+"*"+CHR$(bezz&)+"-"+CHR$(bezz&-1)+"*"+CHR$(bezz&+32)+")/"+CHR$(bezz&)+"^2") !,
ELSE IF t&=1 !hoch
IF VAL?(b$)=LEN(b$) !f^C
ret$=@mul$(@mul$(a_abl$,b$),@hoch$(a$,STR$(VAL(b$)-1)))
@print(CHR$(bez&+32)+"="+CHR$(bezz&-1+32)+"*"+CHR$(bezz&)+"*"+CHR$(bezz&-1)+"^("+CHR$(bezz&)+"-1)") !,
ELSE !f^g
IF a$<>"E"
ret$=@mul$(@add$(@mul$(@div$(a_abl$,a$),b$),@mul$("LN("+a$+")",b_abl$)),f$)
@print(CHR$(bez&+32)+"=("+CHR$(bezz&-1+32)+"/"+CHR$(bezz&-1)+"*"+CHR$(bezz&)+"+LN("+CHR$(bezz&+32)+")*"+CHR$(bezz&+32)+")*"+CHR$(bez&)) !,
ELSE !E^g
ret$=@mul$(@add$(@mul$(@div$(a_abl$,a$),b$),b_abl$),f$)
@print(CHR$(bez&+32)+"=("+CHR$(bezz&-1+32)+"/"+CHR$(bezz&-1)+"*"+CHR$(bezz&)+"+"+CHR$(bezz&+32)+")*"+CHR$(bez&)) !,
ENDIF
ENDIF
ENDIF
ENDIF
IF vorz!
ret$=@mul$(ret$,"-1")
f$="-"+f$
ENDIF
IF (f$="X" OR @const(f$))=FALSE AND t&=0
@print(CHR$(bez&)+"="+f$) !,
ENDIF
@print(CHR$(bez&+32)+"="+ret$)
RETURN ret$
ENDFUNC
> FUNCTION vorz(VAR f$)
LOCAL vorz!,a$,pos&
' vorz! :das Vorzeichen, Rückgabewert (negativ=TRUE)
' a$ :zur Kontrolle, ob abgebrochen werden kann
' pos& :nicht weiter benötigte Variable für den @trenn()-Aufruf
'
REPEAT
a$=f$
IF LEFT$(f$)="+"
f$=MID$(f$,2,LEN(f$)-1)
ENDIF
'
' Der @trenn()-Aufruf verhindert, das der gesamten Funktion
' ein falsches Vorzeichen gegeben wird.
IF LEFT$(f$)="-" AND @trenn(f$,pos&)<=3
IF vorz!
vorz!=FALSE
ELSE
vorz!=TRUE
ENDIF
f$=MID$(f$,2,LEN(f$)-1)
ENDIF
f$=@kl_weg$(f$)
UNTIL a$=f$
RETURN vorz!
ENDFUNC
> FUNCTION trenn(f$,VAR pos&)
LOCAL i&,a$,kl&,j&,t&,eben!
' i& :die Postition des aktuellen Zeichens
' a$ :das aktuelle Zeichen
' kl& :die Anzahl der bei i& geöffneten Klammern
' j& :Schleifenvariable, zum Suchen einer neuen Trennstelle benötigt
' t& :der Wert der aktuellen Trennstelle, Rückgabewert
' eben! :gibt an, ob letztes a$ Verknüpfungszeichen war (dann TRUE),
' also Vorzeichen folgen können (daher erst TRUE)
i&=1
pos&=1
a$="*"
REPEAT
IF (a$="+" OR a$="-")=FALSE
eben!=(a$="*" OR a$="/" OR a$="^")
ENDIF
a$=MID$(f$,i&,1)
IF a$="("
INC kl&
ELSE IF a$=")"
DEC kl&
ENDIF
IF kl&=0
FOR j&=5 DOWNTO 1
IF a$=tr$(j&) AND j&=>t&
IF j&<4 OR eben!=FALSE
t&=j&
pos&=i&
ENDIF
ENDIF
NEXT j&
ENDIF
INC i&
UNTIL i&>=LEN(f$)
RETURN t&
ENDFUNC
> FUNCTION klammer$(f$,wert&)
LOCAL t&,pos&
' t& :Wert der Trennstelle
' pos& :für den @trenn()-Aufruf, dummy
'
t&=@trenn(f$,pos&)
IF wert&<t&
f$="("+f$+")"
ENDIF
RETURN f$
ENDFUNC
> FUNCTION kl_weg$(f$)
LOCAL t&,pos&
' t& :Wert der Trennstelle
' pos& :für den @trenn()-Aufruf, dummy
'
WHILE LEFT$(f$)="(" AND RIGHT$(f$)=")" AND t&=0
t&=@trenn(f$,pos&)
IF t&=0
f$=MID$(f$,2,LEN(f$)-2)
IF INSTR(f$,"(")>INSTR(f$,")")
f$="("+f$+")"
t&=1
ENDIF
' Wenn bei (x)(x+3) ("*" fehlt) die Klammern gelöscht wurden
' werden sie wieder hinzugefügt, um übersichtlicher zu
' bleiben. Der Fehler wird später ausgegeben.
ENDIF
WEND
RETURN f$
ENDFUNC
'
> FUNCTION add$(a$,b$)
IF a$="0"
RETURN b$
ELSE IF b$="0"
RETURN a$
ENDIF
RETURN a$+"+"+b$
ENDFUNC
> FUNCTION sub$(a$,b$)
b$=@klammer$(b$,3)
IF b$="0"
RETURN a$
ELSE IF a$="0"
RETURN "-"+b$
ENDIF
a$=@klammer$(a$,5)
RETURN a$+"-"+b$
ENDFUNC
> FUNCTION mul$(a$,b$)
IF a$="0" OR b$="0"
RETURN "0"
ELSE IF a$="1"
RETURN b$
ELSE IF b$="1"
RETURN a$
ELSE IF b$="-1"
RETURN "-"+@klammer$(a$,3)
ENDIF
a$=@klammer$(a$,3)
b$=@klammer$(b$,3)
RETURN a$+"*"+b$
ENDFUNC
> FUNCTION div$(a$,b$)
IF a$="0" AND b$<>"0"
RETURN "0"
ELSE IF b$="1"
RETURN a$
ENDIF
a$=@klammer$(a$,3)
b$=@klammer$(b$,1)
RETURN a$+"/"+b$
ENDFUNC
> FUNCTION hoch$(a$,b$)
IF b$="1"
RETURN a$
ELSE IF b$="0" AND a$<>"0"
RETURN "1"
ELSE IF a$="0" AND b$<>"0"
RETURN "0"
ENDIF
a$=@klammer$(a$,1)
b$=@klammer$(b$,0)
RETURN a$+"^"+b$
ENDFUNC
'
> FUNCTION const(a$)
IF LEN(a$)=VAL?(a$) OR a$="A" OR a$="E"
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNC